import { Response } from 'express';
import { Expense } from '@/models/Expense';
import { Car } from '@/models/Vehicle';
import { AuthenticatedRequest } from '@/middleware/auth';
import { IExpenseWithStats } from '@/types';

/**
 * @swagger
 * /api/expenses:
 *   post:
 *     summary: 创建费用记录
 *     tags: [费用记录]
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - vehicleId
 *               - type
 *               - mileage
 *               - date
 *             properties:
 *               vehicleId:
 *                 type: string
 *                 description: 车辆ID
 *               type:
 *                 type: string
 *                 enum: [加油, 保养, 维修, 停车费, 年检, 保险, 罚单, 过路费, 拖车费, 洗车费, 车位费]
 *                 description: 费用类型
 *               mileage:
 *                 type: number
 *                 description: 里程数
 *               fuelInfo:
 *                 type: object
 *                 properties:
 *                   showPrice:
 *                     type: number
 *                     description: 表显单价
 *                   actualPrice:
 *                     type: number
 *                     description: 实付单价
 *                   showAmount:
 *                     type: number
 *                     description: 表显金额
 *                   fuelAmount:
 *                     type: number
 *                     description: 加油量
 *                   discountAmount:
 *                     type: number
 *                     description: 优惠金额
 *                   actualAmount:
 *                     type: number
 *                     description: 实付金额
 *               isFull:
 *                 type: boolean
 *                 description: 邮箱是否加满
 *                 default: false
 *               isRecord:
 *                 type: boolean
 *                 description: 上次是否记录
 *                 default: false
 *               isWarning:
 *                 type: boolean
 *                 description: 油箱灯是否亮
 *                 default: false
 *               currency:
 *                 type: string
 *                 enum: [CNY, USD, EUR]
 *                 description: 货币
 *                 default: CNY
 *               date:
 *                 type: string
 *                 format: date
 *                 description: 费用日期
 *               notes:
 *                 type: string
 *                 description: 备注
 *               location:
 *                 type: string
 *                 description: 费用地点
 *               amount:
 *                 type: number
 *                 description: 费用金额
 *               odometer:
 *                 type: number
 *                 description: 里程表
 *               description:
 *                 type: string
 *                 description: 描述
 *               imageUrl:
 *                 type: string
 *                 description: 图片URL
 *     responses:
 *       201:
 *         description: 创建成功
 *       400:
 *         description: 请求参数错误
 */
export const createExpense = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const {
      vehicleId,
      type,
      mileage,
      fuelInfo,
      isFull = false,
      isRecord = false,
      isWarning = false,
      currency = 'CNY',
      date,
      notes,
      location,
      odometer,
      description,
      imageUrl,
    } = req.body;

    // 验证车辆是否存在且属于当前用户
    const car = await Car.findOne({
      _id: vehicleId,
      userId: req.userId,
    });
    if (!car) {
      res.status(404).json({
        success: false,
        message: '车辆不存在',
      });
      return;
    }

    // 数据验证和类型转换
    if (!mileage || typeof mileage !== 'number') {
      res.status(400).json({
        success: false,
        message: '里程数必须是有效的数字',
      });
      return;
    }

    // 处理日期字段 - 接收时间戳
    let processedDate;
    if (typeof date === 'string') {
      // 如果是时间戳字符串，转换为数字
      if (/^\d+$/.test(date)) {
        processedDate = new Date(parseInt(date));
      } else {
        processedDate = new Date(date);
      }
    } else if (typeof date === 'number') {
      processedDate = new Date(date);
    } else {
      processedDate = new Date();
    }

    // 验证日期是否有效
    if (isNaN(processedDate.getTime())) {
      res.status(400).json({
        success: false,
        message: '日期格式无效',
      });
      return;
    }

    // 处理fuelInfo字段
    let processedFuelInfo = fuelInfo;
    if (fuelInfo && typeof fuelInfo === 'object') {
      processedFuelInfo = {
        showPrice:
          typeof fuelInfo.showPrice === 'string'
            ? parseFloat(fuelInfo.showPrice)
            : fuelInfo.showPrice,
        actualPrice:
          typeof fuelInfo.actualPrice === 'string'
            ? parseFloat(fuelInfo.actualPrice)
            : fuelInfo.actualPrice,
        showAmount:
          typeof fuelInfo.showAmount === 'string'
            ? parseFloat(fuelInfo.showAmount)
            : fuelInfo.showAmount,
        fuelAmount:
          typeof fuelInfo.fuelAmount === 'string'
            ? parseFloat(fuelInfo.fuelAmount)
            : fuelInfo.fuelAmount,
        fuelType: fuelInfo.fuelType,
        discountAmount:
          typeof fuelInfo.discountAmount === 'string'
            ? parseFloat(fuelInfo.discountAmount)
            : fuelInfo.discountAmount,
        actualAmount:
          typeof fuelInfo.actualAmount === 'string'
            ? parseFloat(fuelInfo.actualAmount)
            : fuelInfo.actualAmount,
      };

      // 验证必要的fuelInfo字段
      if (type === '加油') {
        if (
          !processedFuelInfo.showPrice ||
          !processedFuelInfo.showAmount ||
          !processedFuelInfo.fuelAmount
        ) {
          res.status(400).json({
            success: false,
            message: '加油记录必须包含表显单价、表显金额和加油量',
          });
          return;
        }
      }
    }

    const expense = new Expense({
      userId: req.userId,
      vehicleId,
      type,
      mileage,
      fuelInfo: processedFuelInfo,
      isFull,
      isRecord,
      isWarning,
      currency,
      date: processedDate,
      notes,
      location,
      odometer,
      description,
      imageUrl,
    });

    await expense.save();

    // 转换为对象并添加时间戳字段
    const expenseObj = expense.toObject() as IExpenseWithStats;

    // 将时间字段转换为时间戳
    expenseObj.createdAt = expense.createdAt
      ? expense.createdAt.getTime()
      : null;
    expenseObj.updatedAt = expense.updatedAt
      ? expense.updatedAt.getTime()
      : null;
    expenseObj.date = expense.date ? expense.date.getTime() : null;

    // 同时保留时间戳字段（向后兼容）
    expenseObj.createdAtTimestamp = expenseObj.createdAt;
    expenseObj.updatedAtTimestamp = expenseObj.updatedAt;
    expenseObj.dateTimestamp = expenseObj.date;

    res.status(201).json({
      success: true,
      message: '费用记录创建成功',
      data: expenseObj,
    });
  } catch (error) {
    console.error('createExpense error:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误',
    });
  }
};

/**
 * @swagger
 * /api/expenses:
 *   get:
 *     summary: 获取费用记录列表
 *     tags: [费用记录]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *         description: 页码
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 10
 *         description: 每页数量
 *       - in: query
 *         name: vehicleId
 *         schema:
 *           type: string
 *         description: 车辆ID筛选
 *       - in: query
 *         name: type
 *         schema:
 *           type: string
 *         description: 费用类型筛选
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 开始日期
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: 结束日期
 *     responses:
 *       200:
 *         description: 获取成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                 message:
 *                   type: string
 *                 data:
 *                   type: object
 *                   properties:
 *                     expenses:
 *                       type: array
 *                       items:
 *                         type: object
 *                         properties:
 *                           _id:
 *                             type: string
 *                           createdAtTimestamp:
 *                             type: number
 *                             description: 创建时间戳
 *                           updatedAtTimestamp:
 *                             type: number
 *                             description: 更新时间戳
 *                           dateTimestamp:
 *                             type: number
 *                             description: 费用日期时间戳
 *                           stats:
 *                             type: object
 *                             description: 统计信息（从第二条加油记录开始计算）
 *                             properties:
 *                               distance:
 *                                 type: number
 *                                 description: 行驶里程（公里）
 *                               fuelConsumptionPer100km:
 *                                 type: number
 *                                 description: 百公里油耗（升/百公里）
 *                               costPer100km:
 *                                 type: number
 *                                 description: 百公里费用（元/百公里）
 *                               fuelConsumption:
 *                                 type: number
 *                                 description: 消耗油量
 *                               previousMileage:
 *                                 type: number
 *                                 description: 上次里程
 *                               currentMileage:
 *                                 type: number
 *                                 description: 当前里程
 *                     pagination:
 *                       type: object
 *                       properties:
 *                         page:
 *                           type: number
 *                         limit:
 *                           type: number
 *                         total:
 *                           type: number
 *                         totalPages:
 *                           type: number
 */
export const getExpenses = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const {
      page = 1,
      limit = 10,
      vehicleId,
      type,
      startDate,
      endDate,
    } = req.query;
    const skip = (Number(page) - 1) * Number(limit);

    const filter: any = { userId: req.userId };
    if (vehicleId) filter.vehicleId = vehicleId;
    if (type) filter.type = type;
    if (startDate || endDate) {
      filter.date = {};
      if (startDate) filter.date.$gte = new Date(startDate as string);
      if (endDate) filter.date.$lte = new Date(endDate as string);
    }

    const expenses = await Expense.find(filter)
      .sort({ date: -1 })
      .skip(skip)
      .limit(Number(limit));

    const total = await Expense.countDocuments(filter);

    // 获取所有加油记录用于统计计算（跨页面查询）
    const allFuelExpenses = await Expense.find({
      ...filter,
      type: '加油',
    }).sort({ mileage: 1 }); // 按里程升序排列，便于计算

    console.log(`📊 找到 ${allFuelExpenses.length} 条加油记录用于统计计算`);

    // 计算统计信息
    const expensesWithStats: IExpenseWithStats[] = expenses.map(expense => {
      const expenseObj = expense.toObject() as IExpenseWithStats;

      // 将时间字段转换为时间戳
      expenseObj.createdAt = expense.createdAt
        ? expense.createdAt.getTime()
        : null;
      expenseObj.updatedAt = expense.updatedAt
        ? expense.updatedAt.getTime()
        : null;
      expenseObj.date = expense.date ? expense.date.getTime() : null;

      // 同时保留时间戳字段（向后兼容）
      expenseObj.createdAtTimestamp = expenseObj.createdAt;
      expenseObj.updatedAtTimestamp = expenseObj.updatedAt;
      expenseObj.dateTimestamp = expenseObj.date;

      // 只为加油记录计算统计信息
      if (expense.type === '加油') {
        // 在所有加油记录中找到当前记录的位置
        const currentFuelIndex = allFuelExpenses.findIndex(
          fuelExpense => fuelExpense._id.toString() === expense._id.toString()
        );

        console.log(`🔍 计算统计信息 - 加油记录:`);
        console.log(`   当前记录: ID=${expense._id}, 里程=${expense.mileage}`);
        console.log(
          `   在所有加油记录中的位置: ${currentFuelIndex + 1}/${allFuelExpenses.length}`
        );

        // 如果不是第一条加油记录，计算统计信息
        if (currentFuelIndex > 0) {
          const previousFuelExpense = allFuelExpenses[currentFuelIndex - 1]; // 前一条加油记录

          if (
            previousFuelExpense &&
            expense.mileage &&
            previousFuelExpense.mileage &&
            expense.fuelInfo &&
            expense.fuelInfo.fuelAmount &&
            expense.fuelInfo.fuelAmount > 0
          ) {
            // 计算行驶里程
            const distance = expense.mileage - previousFuelExpense.mileage;

            console.log(
              `   ✅ 找到上次加油记录: ID=${previousFuelExpense._id}, 里程=${previousFuelExpense.mileage}`
            );
            console.log(`   📏 行驶里程: ${distance}km`);

            if (distance > 0) {
              // 计算百公里油耗
              const fuelConsumptionPer100km =
                (expense.fuelInfo.fuelAmount / distance) * 100;

              // 计算百公里费用
              const totalAmount = expenseObj.totalAmount || 0;
              const costPer100km = (totalAmount / distance) * 100;

              console.log(`   ⛽ 加油量: ${expense.fuelInfo.fuelAmount}L`);
              console.log(`   💰 费用: ${totalAmount}元`);
              console.log(
                `   📊 百公里油耗: ${fuelConsumptionPer100km.toFixed(2)}L/100km`
              );
              console.log(
                `   📊 百公里费用: ${costPer100km.toFixed(2)}元/100km`
              );

              // 添加统计字段
              expenseObj.stats = {
                distance, // 行驶里程
                fuelConsumptionPer100km:
                  Math.round(fuelConsumptionPer100km * 100) / 100, // 百公里油耗，保留2位小数
                costPer100km: Math.round(costPer100km * 100) / 100, // 百公里费用，保留2位小数
                fuelConsumption: expense.fuelInfo.fuelAmount, // 消耗油量
                previousMileage: previousFuelExpense.mileage, // 上次里程
                currentMileage: expense.mileage, // 当前里程
              };
            } else {
              console.log(`   ⚠️  里程差为0或负数(${distance})，跳过统计计算`);
            }
          } else {
            console.log(`   ⚠️  缺少必要数据，跳过统计计算`);
            console.log(
              `      previousFuelExpense存在: ${!!previousFuelExpense}`
            );
            console.log(`      当前里程: ${expense.mileage}`);
            console.log(`      上次里程: ${previousFuelExpense?.mileage}`);
            console.log(`      fuelInfo存在: ${!!expense.fuelInfo}`);
            console.log(`      加油量: ${expense.fuelInfo?.fuelAmount}`);
          }
        } else {
          console.log(`   📝 第一条加油记录，无统计信息`);
        }
      }

      return expenseObj;
    });

    res.status(200).json({
      success: true,
      message: '获取费用记录列表成功',
      data: {
        expenses: expensesWithStats,
        pagination: {
          page: Number(page),
          limit: Number(limit),
          total,
          totalPages: Math.ceil(total / Number(limit)),
        },
      },
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '服务器内部错误',
    });
  }
};

/**
 * @swagger
 * /api/expenses/{id}:
 *   get:
 *     summary: 获取费用记录详情
 *     tags: [费用记录]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *         description: 费用记录ID
 *     responses:
 *       200:
 *         description: 获取成功
 *       404:
 *         description: 费用记录不存在
 */
export const getExpenseById = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { id } = req.params;

    const expense = await Expense.findOne({ _id: id, userId: req.userId });
    if (!expense) {
      res.status(404).json({
        success: false,
        message: '费用记录不存在',
      });
      return;
    }

    // 转换为对象并添加时间戳
    const expenseObj = expense.toObject() as IExpenseWithStats;

    // 将时间字段转换为时间戳
    expenseObj.createdAt = expense.createdAt
      ? expense.createdAt.getTime()
      : null;
    expenseObj.updatedAt = expense.updatedAt
      ? expense.updatedAt.getTime()
      : null;
    expenseObj.date = expense.date ? expense.date.getTime() : null;

    // 同时保留时间戳字段（向后兼容）
    expenseObj.createdAtTimestamp = expenseObj.createdAt;
    expenseObj.updatedAtTimestamp = expenseObj.updatedAt;
    expenseObj.dateTimestamp = expenseObj.date;

    res.status(200).json({
      success: true,
      message: '获取费用记录详情成功',
      data: expenseObj,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '服务器内部错误',
    });
  }
};

/**
 * @swagger
 * /api/expenses/{id}:
 *   put:
 *     summary: 更新费用记录
 *     tags: [费用记录]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *         description: 费用记录ID
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               type:
 *                 type: string
 *                 description: 费用类型
 *               amount:
 *                 type: number
 *                 description: 费用金额
 *               date:
 *                 type: string
 *                 format: date
 *                 description: 费用日期
 *               odometer:
 *                 type: number
 *                 description: 里程表
 *               description:
 *                 type: string
 *                 description: 描述
 *               imageUrl:
 *                 type: string
 *                 description: 图片URL
 *     responses:
 *       200:
 *         description: 更新成功
 *       404:
 *         description: 费用记录不存在
 */
export const updateExpense = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { id } = req.params;
    const updateData = req.body;

    // 移除不允许更新的字段
    delete updateData.userId;
    delete updateData.vehicleId;

    if (updateData.date) {
      updateData.date = new Date(updateData.date);
    }

    const expense = await Expense.findOneAndUpdate(
      { _id: id, userId: req.userId },
      updateData,
      { new: true, runValidators: true }
    );

    if (!expense) {
      res.status(404).json({
        success: false,
        message: '费用记录不存在',
      });
      return;
    }

    res.status(200).json({
      success: true,
      message: '更新费用记录成功',
      data: expense,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '服务器内部错误',
    });
  }
};

/**
 * @swagger
 * /api/expenses/{id}:
 *   delete:
 *     summary: 删除费用记录
 *     tags: [费用记录]
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *         description: 费用记录ID
 *     responses:
 *       200:
 *         description: 删除成功
 *       404:
 *         description: 费用记录不存在
 */
export const deleteExpense = async (
  req: AuthenticatedRequest,
  res: Response
): Promise<void> => {
  try {
    const { id } = req.params;

    const expense = await Expense.findOneAndDelete({
      _id: id,
      userId: req.userId,
    });
    if (!expense) {
      res.status(404).json({
        success: false,
        message: '费用记录不存在',
      });
      return;
    }

    res.status(200).json({
      success: true,
      message: '删除费用记录成功',
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: '服务器内部错误',
    });
  }
};
